/************************************************
 * Author       :   XXY
 * Blog         :   https://www.cnblogs.com/jzyl
 * Gitee        :   https://gitee.com/xiaobaichong
 * Email        :   1047185209@QQ.com
 * FileName     :   EntityBase.cs
 * CreateData   :   2023/4/28 18:02:16
 * UnityVersion :   2020.3.33f1c2
 * Description  :   实体基类
************************************************/

using Main;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Hotfix
{
    /// <summary>
    /// 实体即为容器(个体)
    /// 实体基类
    /// </summary>
    internal class EntityBase : IEntity
    {
        private bool active = true;

        private Dictionary<Type, ComponentBase> components = new Dictionary<Type, ComponentBase>();
        private Dictionary<Type, SystemBase> systems = new Dictionary<Type, SystemBase>();

        #region 属性
        /// <summary>
        /// 实体名称
        /// </summary>
        public string Name { get; private set; }
        /// <summary>
        /// 启用禁用实体
        /// </summary>
        public bool Enable
        {
            get
            {
                return active;
            }
            set
            {
                if (Scene.isLoaded && active != value)
                {
                    if (value)
                    {
                        foreach (var system in GetAllSystem)
                        {
                            system.SystemCallback.Emit(SystemCallbackType.Awake);
                        }
                        foreach (var system in GetAllSystem)
                        {
                            if (system.Enable)
                            {
                                system.SystemCallback.Emit(SystemCallbackType.OnEnable);
                            }
                        }
                        foreach (var system in GetAllSystem)
                        {
                            if (system.Enable)
                            {
                                system.SystemCallback.Emit(SystemCallbackType.Start);
                            }
                        }
                    }
                    else
                    {
                        foreach (SystemBase system in GetAllSystem)
                        {
                            if (system.Enable)
                            {
                                system.SystemCallback.Emit(SystemCallbackType.OnDisable);
                            }
                        }
                    }
                }
                active = value;
            }
        }
        /// <summary>
        /// 是否已经初始化实体
        /// </summary>
        public bool IsInit { get; private set; }
        /// <summary>
        /// 获取实体所在的场景
        /// </summary>
        public SceneBase Scene { get; private set; }
        #endregion
        #region 组件

        public ComponentBase AddComponent(ComponentBase component)
        {
            Type t = component.GetType();
            if (components.ContainsKey(t))
            {
                throw new Exception($"该Entity 一包含 该组件");
            }
            else
            {
                components.Add(t, component);
                return component;
            }
        }

        public T AddComponent<T>(ComponentIDE componentIDE) where T : ComponentBase
        {
            T value = ComponentUtility.CreateComponent<T>(componentIDE);
            return (T)AddComponent(value);
        }
        public T AddComponent<T>(VariablesIDE variablesIDE) where T : ComponentBase
        {
            T value = ComponentUtility.CreateComponent<T>(variablesIDE);
            return (T)AddComponent(value);
        }

        public T GetComponent<T>() where T : ComponentBase
        {
            ComponentBase component;
            if (!this.components.TryGetValue(typeof(T), out component))
            {
                return default(T);
            }
            return (T)component;
        }

        public bool RemoveComponent<T>()
        {
            return this.components.Remove(typeof(T));
        }
        /// <summary>
        /// 获取实体所有组件
        /// </summary>
        public Dictionary<Type, ComponentBase>.ValueCollection GetComponentBases
        {
            get
            {
                return components.Values;
            }
        }
        #endregion
        #region 系统

        public T AddSystem<T>() where T : SystemBase
        {
            Type type = typeof(T);
            if (systems.ContainsKey(type))
            {
                throw new Exception($"该Entity 已包含 该系统");
            }
            else
            {
                T instance = Utility.CreateInstance<T>();
                systems.Add(type, instance);
                Utility.SetPropertyValue(instance, "Entity", this);
                if (Enable && Scene.isLoaded)
                {
                    instance.SystemCallback.Emit(SystemCallbackType.Awake);
                    instance.SystemCallback.Emit(SystemCallbackType.OnEnable);
                    instance.SystemCallback.Emit(SystemCallbackType.Start);
                }
                return instance;
            }
        }
        public bool RemoveSystem<T>() where T : SystemBase
        {
            Type t = typeof(T);
            if (systems.ContainsKey(t))
            {
                SystemBase system = systems[t];
                systems.Remove(t);
                if (Scene.isLoaded)
                {
                    if (Enable)
                    {
                        if (system.Enable)
                        {
                            system.SystemCallback.Emit(SystemCallbackType.OnDisable);
                        }
                    }
                    system.SystemCallback.Emit(SystemCallbackType.OnDestroy);
                }
                return true;
            }
            else
            {
                return false;
            }
        }

        public T GetSystem<T>() where T : SystemBase
        {
            SystemBase system;
            if (!systems.TryGetValue(typeof(T), out system))
            {
                return default(T);
            }
            return (T)system;
        }
        /// <summary>
        /// 获取实体所有组件
        /// </summary>
        /// <returns></returns>
        public Dictionary<Type, SystemBase>.ValueCollection GetAllSystem
        {
            get
            {
                return systems.Values;
            }
        }
        #endregion
        /// <summary>
        /// 实体初始化入口
        /// </summary>
        public virtual void OnInit()
        {

        }
    }
}